package com.duolebo.uteped_sdk;

import android.app.Activity;
import android.util.Log;

import androidx.annotation.NonNull;

import com.duolebo.uteped_sdk.msg.BaseMessage;
import com.duolebo.uteped_sdk.msg.CommonMessage;
import com.duolebo.uteped_sdk.msg.ContactMessage;
import com.duolebo.uteped_sdk.msg.DeviceMessage;
import com.duolebo.uteped_sdk.msg.DeviceOptionMessage;
import com.duolebo.uteped_sdk.msg.HomeMessage;
import com.duolebo.uteped_sdk.msg.MenstrualMessage;
import com.duolebo.uteped_sdk.msg.SedentaryMessage;
import com.duolebo.uteped_sdk.msg.SpaceMessage;
import com.duolebo.uteped_sdk.msg.SportsMessage;
import com.duolebo.uteped_sdk.msg.TimeMessage;
import com.duolebo.uteped_sdk.msg.UpgradeMessage;
import com.duolebo.uteped_sdk.msg.WatchFaceMessage;
import com.duolebo.uteped_sdk.msg.WeatherMessage;
import com.duolebo.uteped_sdk.utils.Const;

import java.util.HashMap;
import java.util.Map;

import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;

/**
 * @Author: LiuYang
 * @Date: 2023/12/11 12:39
 * @Description:
 */
public class UTEPedMethodCallHandler implements MethodChannel.MethodCallHandler{
    private final static String TAG = "UTEPedMethodCallHandler";
    private final static String M_localNotify = "localNotify";

    private static UTEPedMethodCallHandler instance;

    final private UTEPedEventHandler utePedEventHandler;

    private final Map<String, BaseMessage> messageMap = new HashMap<>();

    final private MethodChannel methodChannel;

    public static UTEPedMethodCallHandler shareInstance() {
        return instance;
    }

    public UTEPedMethodCallHandler(Activity context, BinaryMessenger binaryMessenger) {
        this.methodChannel = new MethodChannel(binaryMessenger, Const.METHOD_CHANNEL);
        this.utePedEventHandler = new UTEPedEventHandler(binaryMessenger);
        this.methodChannel.setMethodCallHandler(this);

        initMessages();

        instance = this;
    }

    private void initMessages() {
        messageMap.clear();

        DeviceMessage deviceMsg = new DeviceMessage(methodChannel, utePedEventHandler);
        messageMap.put(deviceMsg.getPath(), deviceMsg);
        UTEPedBleClientHelper.shareInstance().addDeviceNotifyListener(deviceMsg);
        UTEPedBleClientHelper.shareInstance().addBleConnectStateListener(deviceMsg);

        CommonMessage commonMessage = new CommonMessage(methodChannel, utePedEventHandler);
        messageMap.put(commonMessage.getPath(), commonMessage);

        HomeMessage homeMessage = new HomeMessage(methodChannel, utePedEventHandler);
        messageMap.put(homeMessage.getPath(), homeMessage);

        SpaceMessage spaceMessage = new SpaceMessage(methodChannel, utePedEventHandler);
        messageMap.put(spaceMessage.getPath(), spaceMessage);

        SportsMessage sportsMessage = new SportsMessage(methodChannel, utePedEventHandler);
        messageMap.put(sportsMessage.getPath(), sportsMessage);

        UTEPedBleClientHelper.shareInstance().addDeviceNotifyListener(sportsMessage);

        DeviceOptionMessage deviceOptionMessage = new DeviceOptionMessage(methodChannel, utePedEventHandler);
        messageMap.put(deviceOptionMessage.getPath(), deviceOptionMessage);

        ContactMessage contactMessage = new ContactMessage(methodChannel, utePedEventHandler);
        messageMap.put(contactMessage.getPath(), contactMessage);

        MenstrualMessage menstrualMessage = new MenstrualMessage(methodChannel, utePedEventHandler);
        messageMap.put(menstrualMessage.getPath(), menstrualMessage);

        WeatherMessage weatherMessage = new WeatherMessage(methodChannel, utePedEventHandler);
        messageMap.put(weatherMessage.getPath(), weatherMessage);

        UTEPedBleClientHelper.shareInstance().addDeviceNotifyListener(weatherMessage);

        WatchFaceMessage watchFaceMessage = new WatchFaceMessage(methodChannel, utePedEventHandler);
        messageMap.put(watchFaceMessage.getPath(), watchFaceMessage);

        UpgradeMessage upgradeMessage = new UpgradeMessage(methodChannel, utePedEventHandler);
        messageMap.put(upgradeMessage.getPath(), upgradeMessage);

        SedentaryMessage sedentaryMessage = new SedentaryMessage(methodChannel, utePedEventHandler);
        messageMap.put(sedentaryMessage.getPath(), sedentaryMessage);

        TimeMessage timeMessage = new TimeMessage(methodChannel, utePedEventHandler);
        messageMap.put(timeMessage.getPath(), timeMessage);
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
        boolean consumed = false;
        if (call.method.equals("getPlatformVersion")) {
            result.success("Android " + android.os.Build.VERSION.RELEASE);
            consumed = true;
        }
        if (call.hasArgument(Const.KEY_PATH)) {
            String path = call.argument(Const.KEY_PATH);
            if (path != null && messageMap.containsKey(path)) {
                Log.d(TAG, "onMethodCall path:" + path + " method: " + call.method);
                BaseMessage message = messageMap.get(path);
                if (message != null && message.methodCallConsumed(call, result)) {
                    consumed = true;
                }
            }
        }
        if (!consumed) {
            result.notImplemented();
        }
    }

    public void onDetached(ActivityPluginBinding binding) {
        this.methodChannel.setMethodCallHandler(null);

        for (String key: messageMap.keySet()) {
            BaseMessage message = messageMap.get(key);
            if (message != null) {
                message.release();
            }
        }

        messageMap.clear();
        instance = null;
    }


    /**
     * 推送本地消息
     * @param action 类型
     * @param value 值
     */
    public void publishLocal(String action, String value) {
        Map<String, Object> map = new HashMap<>();
        map.put(Const.KEY_PATH, "");
        map.put(Const.KEY_METHOD, M_localNotify);
        map.put(Const.KEY_ACTION, action);
        map.put(Const.KEY_VALUE, value);
        utePedEventHandler.publishEvent(map);
    }

}
